
import threading
from common.utils import *
from get_config import pp

num_device = pp

class Value:
    ON = 1
    OFF = 0
    def set(self, x):
        return x
    def is_implemented(self):
        return True

def cam_thread(ss):
    ttt = 3
    while(ss.is_stream_on):
        t0 = time.time()
        ss.img = ss.getFrame()
        #ss.frame_callback([ss.img,ss.index])
        if ss.frame_callback is not None:
            ss.frame_callback(ss.img)
        tt = time.time()-t0
        if tt<ttt:
            time.sleep(ttt-tt)

def GetCamNum():
    return len(pp)

class MVSCam:

    def __init__(self, index=None, triggermode='off', frame_callback=None) -> None:
        self.ExposureTime = Value()
        self.TriggerMode = Value()
        self.TriggerSource = Value()
        self.PixelColorFilter = Value()
        self.triggermode = triggermode
        self.frame_callback = frame_callback
        self.data_stream = []
        if index is not None:
            self.open(index, triggermode, frame_callback)
        self.index = index
        self.i = 0
        self.img = None
        self.is_stream_on = True
        self.cam_thread_handle = None

    def OpenDevice(self):
        self.open(0)
    
    def CloseDevice(self):
        self.open(0)
    
    def get_numpy_array(self):
        return self.img
    
    def get_status(self):
        return 0
    
    def convert(self, ss):
        return self
    
    def StartContinusAcqCallback(self):
        pass
    
    def stream_on(self):
        self.is_stream_on = True
        self.cam_thread_handle = threading.Thread(target=cam_thread, args=(self,))
        self.cam_thread_handle.start()
    
    def stream_off(self):
        self.is_stream_on = False
        if self.cam_thread_handle is not None:
            self.cam_thread_handle.join()
    
    def close_device(self):
        pass
    
    def register_capture_callback(self, fun):
        self.frame_callback = fun

    def open(self, index, triggermode='off', frame_callback=None):
        index = str(index)
        if '.' in index:
            index = index.split('.')[-1]
        self.index = index
        self.triggermode = triggermode
        self.frame_callback = frame_callback
        pa = pp[f'{index}']
        self.li = listdir(pa, ['.jpg', '.png', '.bmp'])
        self.li = [f'{pa}/{x}' for x in self.li]
        self.i = 400
        if len(self.li) ==0:
            return 0
        
        if triggermode in ['hard']:
            self.stream_on()
        return 1

    def close(self):
        self.stream_off()
        self.i = 0
        return 0

    def stop(self):
        self.i = 0
        return 0

    def getFrame(self):
        if self.i >= len(self.li):
            self.i = 0

        if self.i < len(self.li):
            #print(f'getFrame {self.i} {self.li[self.i]}')
            im = cv_imread(self.li[self.i], 1)
            self.i += 1
            return im

        return None


class DeviceManager:
    def update_device_list(self):
        return 4, []

    def open_device_by_index(self, index):
        return MVSCam(index-1)

GxSwitchEntry = Value()

def test_MVSCams():
    ncam = GetCamNum()
    cams = [MVSCam() for i in range(ncam)]
    [cams[i].open(ip) for i, ip in enumerate(pp.keys())]
    for ii in range(100):
        ims = [cams[i].getFrame() for i in range(ncam)]
        ims = [cv2.resize(ims[i], (640, 480)) for i in range(ncam)]
        [cv2.imshow(f'im{i}', ims[i]) for i in range(ncam)]
        print(ii)
        cv2.waitKey(100)

    [cams[i].stop() for i in range(ncam)]
    print('end')


def test_MVSCam_tri():
    cam = MVSCam()
    import queue
    qq = queue.Queue(maxsize=1)

    def get_call(index):
        def frame_callback(im):
            #im = cv2.resize(im, (640, 480))
            qq.put([index, im])
        return frame_callback

    cam.open(0, 'hard', get_call(0))
    im = np.zeros((480, 640, 3), dtype='uint8')
    for i in range(1000):
        index, im = qq.get()
        im = cv2.resize(im, (640, 480))
        cv2.imshow(f'im{index}', im)
        cv2.waitKey(10)
        print('time out')

    cam.stop()


if __name__ == "__main__":
    test_MVSCams()
    #test_MVSCam_tri()

